/**
  本类实例化后任然需要调用setControlALL(bool value){controlALL=value;}为true才会启用槽
  本程序存在崩溃的可能,即有时成功有时崩,原因应该属于超界访问,但是为何有时候会有时候没呢,怪怪的
  阈值需要一定的干预修正
  使用
  1.实例化
  2.setControlALL(true);
  3.开启采样一段时间后关闭
  4.出现声音时就会自动处理了
  比如自动打开文件保存
*/

#ifndef LISOUNDLISTEN_H
#define LISOUNDLISTEN_H

#include <QObject>
#include <QAudioFormat>
#include <QAudioDeviceInfo>
#include <QAudioInput>
#include <QFile>
#include "../DataStructure/limitqueue.h"
#include <QDebug>

#include <QTimer>
#include <QStandardPaths>


#include <QAudioOutput>

class LiSoundListen : public QObject
{
    Q_OBJECT
public:
//    explicit LiSoundListen(QObject *parent = 0);
    explicit LiSoundListen(QAudioFormat::Endian byteOrder=QAudioFormat::BigEndian,
                           int channels=1,QString codec="audio/pcm",int samplerate=16000,
                           int sampleSize=16,
                           QAudioFormat::SampleType sampleType=QAudioFormat::SignedInt,
                           QString savePath="/storage/emulated/0/data",
                           QObject *parent = 0);


    ~LiSoundListen();

    //音频格式设置
    void setByteOrder(QAudioFormat::Endian byteOrder)
    {m_audioFormat.setByteOrder (byteOrder);}
    void setChannelCount(int channels)
    {m_audioFormat.setChannelCount (channels);}
    void setCodec(const QString &codec)
    {m_audioFormat.setCodec (codec);}
    void setSampleRate(int samplerate)
    {m_audioFormat.setSampleRate (samplerate);}
    void setSampleSize(int sampleSize)
    {m_audioFormat.setSampleSize (sampleSize);}
    void setSampleType(QAudioFormat::SampleType sampleType)
    {m_audioFormat.setSampleType (sampleType);}


    void setStandardMaxSoundSize(int value){qDebug()<<"改阈值:"<<QString::number (value);
        standardMaxSoundSize=value;}//设置监听触发阈值
    Q_INVOKABLE  int getSampleMaxSoundeSize(){return sampleMaxSoundeSize;}//返回采样最大音量
    Q_INVOKABLE void setControlSampleMaxSoundeSize(bool value);//设置是否开启采样

    void setControlsaveFile(bool isSave);//设置是否允许先保存文件写入数据
    void setControlALL(bool value){controlALL=value;}//总控开关
signals:
    void appearSound();//超过阈值时发射
    void stopSound();//双计时器触发完毕,即无人说话则发出

    void sampleSoundSize(int maxSoundSize);//采样停止时发出,当次采样的最大值


public slots:
    void handleInputData();//主要槽,处理音频输入信息
    void smallTimeOver();//小计时器停止触发
    void bigTimeOver();//大计时器停止触发

    void onAppearSound();//处理对应自身信号
    void onStopSound();//


protected:
    void doubleTimerSet();//两个计时器的配置函数
private :
    QAudioFormat m_audioFormat;//音频格式
    QAudioInput *m_audioInputListen;//音频输入
    QIODevice * m_audioInputListenIO;//音频输入操作对象
//    QByteArray *m_Buffer;
    char *m_Buffer;//指向存储声音位置,频繁的new和delete
    bool controlALL;//是否启用音频处理槽


    int standardMaxSoundSize;//判断是否有人说话的阈值
    int sampleMaxSoundeSize;//采样中的最大声音
    bool controlSampleMaxSoundeSize;//是否采取最大音量值
    int currentMaxSoundeSize;//实时最大声音
    QFile *saveFile;//保存文件对象
    QString savePath;//保存文件路径
    bool controlEmitAppearSound;//是否允许发射有音信号

    bool controlsaveFile;//是否允许写入文件

    QTimer smallTimer;//双计时器处理没人说话判断
    QTimer bigTimer;//
    bool isWrangle;//计时器自启动判断标志之是否有声音

//    test
    QAudioOutput *m_audioOutput;//音频输出
    QIODevice * m_audioOutputListenIO;//音频输出操作对象

    //断头修正
    char *soundHead;
    bool isAppear;
    int soundHeadLen;
    LimitQueue* repaidHeadSave;
};

#endif // LISOUNDLISTEN_H
